/*
 * main.cpp
 *
 *  Created on: 02/07/2011
 *      Author: pablo
 */

#include <string.h>
#include <iostream>
#include <sstream>

#include "Cliente.h"
#include "ConfiguracionAplicacion.h"

#include <stdlib.h>

#include "Writer.h"
#include "Logger.h"
#include <sys/wait.h>

#include "Color.h"


#define BUFFSIZE 1
#define DEBUG_FILENAME "debug"
#define	FILENAME	"history"

using namespace std;

void procesarSalas(string salas){
	bool haySalas = false;
	cout << AZUL << "Numero" << "\t"<< "Nombre"  << RESET_COLOR << endl;
	cout << GRIS << "======" << "\t" << "======" << RESET_COLOR << endl;
	char * pch = strtok((char*) salas.c_str(), ",");

	while (pch != NULL) {
		haySalas = true;
		string linea = pch;
		int posicion = linea.find_first_of("|", 0);
		string idSala = linea.substr(0, posicion);
		string nombreSala = linea.substr(posicion + 1, linea.size());

		cout << TURQUEZA <<idSala << RESET_COLOR << "\t" << VIOLETA << nombreSala << RESET_COLOR << endl;

		pch = strtok(NULL, "\n");
	}

	if (haySalas == false) {
		cout << ROJO << "No hay salas disponibles" << RESET_COLOR << endl << endl;
	}
}

void procesarClientes(string clientes,int idSala){
	bool haySalas = false;
	cout << "Listado de usuarios en la sala:" << idSala << endl;
	char * pch = strtok((char*) clientes.c_str(), ",");
	while (pch != NULL) {
		haySalas = true;
		string cliente = pch;

		cout << cliente << endl;

		pch = strtok(NULL, "\n");
	}

	if (haySalas == false) {
		cout << ROJO << "No hay usuarios conectados" << RESET_COLOR <<endl << endl;
	}
}

int stringToInt(string parametro){
	int numero = 0;
	stringstream streamParametro(parametro);
	streamParametro >> numero;
	return numero;
}

string intToString(int parametro){
	string cadena= "";
	stringstream s;
	s << parametro;
	cadena = s.str();
	return cadena;
}

void showHelp();

int main(int argc, char **argv){
	Logger* logger = new Logger((char *) DEBUG_FILENAME);
	Writer* historyWriter = new Writer((char *) FILENAME);

	string nombre = "";
	string parametro = "";
	int idSala = 0;
	int numeroOpcion = 0;
	bool clienteConfigurado = false;
	mensaje respuesta;
	int opcion;
	string pidCliente = "";

	while ((opcion = getopt (argc, argv, "hd")) != -1){
		switch (opcion){
			case 'd':
				logger->setDebugMode(true);
				break;
			case 'h':
				showHelp();
				exit(0);
				break;
			case '?':
				showHelp();
				exit(0);
				break;
			default:
				cout << "ConcuChat: Opción inválida -" << opcion <<  endl;
				cout << "Use concuchat -h para más información." <<  endl;
				exit(0);
		}
	}

	cout << "Bienvenido al ConcuChat v2.0" << endl;
	cout << "Para comenzar, ingrese su nombre: ";
	getline(cin, nombre);
	mensaje mensajeRecibido;

	Cliente* cliente = new Cliente((char*)ARCHIVO_COLA,LETRA,nombre);
	pidCliente = intToString(cliente->getPid());

	logger->log("Cliente: Ha ingresado un nuevo cliente al chat. Nombre: " + cliente->getNombre());
	logger->log("Cliente: Comienzo a tomar datos de la entrada.");


	while(!clienteConfigurado){

		cout << VERDE << "1." << RESET_COLOR << "Listar salas" << endl;
		cout << VERDE << "2." << RESET_COLOR << "Listar clientes de sala" << endl;
		cout << VERDE << "3." << RESET_COLOR << "Crear nueva sala" << endl;
		cout << VERDE << "4." << RESET_COLOR << "Unirse a una sala" << endl;
		cout << "Seleccione el número de opción:";
		getline(cin, parametro);

		numeroOpcion = stringToInt(parametro);

		switch(numeroOpcion){
			case 1:
				logger->log("Cliente: Selecciono Listar salas.");
				historyWriter->write(pidCliente,cliente->getNombre(), parametro);
				respuesta = cliente->pedirSalas();
				procesarSalas(respuesta.texto);
				break;
			case 2:
				logger->log("Cliente: Selecciono Listar clientes de salas.");
				historyWriter->write(pidCliente,cliente->getNombre(), parametro);
				cout << "Seleccione el número de sala:";
				getline(cin,parametro);
				historyWriter->write(pidCliente,cliente->getNombre(), parametro);
				idSala = stringToInt(parametro);
				respuesta = cliente->pedirUsuariosDeSala(idSala);
				if(respuesta.idSala == -1){
					cout << ROJO << "No existe una sala con ese numero" << RESET_COLOR << endl;
				}else{
					procesarClientes(respuesta.texto,idSala);
				}

				break;
			case 3:
				logger->log("Cliente: Selecciono crear nueva sala.");
				historyWriter->write(pidCliente,cliente->getNombre(), parametro);
				cout << "Ingrese el nombre de la nueva sala:";
				getline(cin,parametro);
				historyWriter->write(pidCliente,cliente->getNombre(), parametro);
				idSala = cliente->crearSala(parametro);
				cliente->setIdSala(idSala);
				clienteConfigurado = true;
				break;
			case 4:
				logger->log("Cliente: Selecciono unirse a una sala.");
				historyWriter->write(pidCliente,cliente->getNombre(), parametro);
				cout << "Seleccione el número de sala:";
				getline(cin,parametro);
				idSala = stringToInt(parametro);
				historyWriter->write(pidCliente,cliente->getNombre(), parametro);
				respuesta = cliente->unirseASala(idSala);

				if(respuesta.idSala == -1){
					cout << ROJO << "No existe una sala con ese numero" << RESET_COLOR << endl;
				}else{
					clienteConfigurado = true;
				}
				break;
		}
	}


	cout << "Se ha unido a la sala de chat, puede comenzar a enviar mensajes" << endl;
	cliente->chatear("Se ha unido a la sala.");
	logger->log("Cliente: Se ha unido a la sala del chat.");
	pid_t pid = fork();
	if (pid == 0) {
		cout << cliente->getNombre() << ":";
		getline(cin,parametro);
		historyWriter->write(pidCliente,cliente->getNombre(), parametro);

		while(parametro.compare("exit") != 0 ){
			cliente->chatear(parametro);
			cout << cliente->getNombre() << ":";
			getline(cin,parametro);
			historyWriter->write(pidCliente,cliente->getNombre(), parametro);

			}

		cliente->chatear("Ha abandonado la sala.");
		cliente->salir();
		exit(0);
	} else {
		bool clienteSaliendo = false;

		while ( !clienteSaliendo){
			logger->log("Servidor: Comienzo a leer los mensajes recibidos.");
			mensajeRecibido = cliente->recibirMensaje();

			if (mensajeRecibido.tipoMensaje == 'S') {
				clienteSaliendo = true;
			} else {
				cout << AZUL << mensajeRecibido.nombreEmisor << ":" << TURQUEZA << mensajeRecibido.texto << RESET_COLOR << endl;
			}
		}
	}
	logger->log("Servidor: Finalizo notificando a los demas clientes.");
	exit(0);

	wait(NULL);
	wait(NULL);
	delete cliente;

	return 0;
}

void showHelp(){
	cout << "..:::ConcuChat:::.." << endl;
	cout << "Aplicación concurrente para conversar. ¡¡Ahora con mensajes!!" << endl;
	cout << "Desarrollado por: " << endl;
	cout <<	"Acosta Claudia Roxana" << endl;
	cout << "Korzeniewski Claudia" << endl;
	cout << "Cufone Pablo Alfonso" << endl;
	cout << endl;
	cout << "Modo de uso: ./concuChat [OPCION]" << endl;
	cout << "-d \t Activa el modo debug." << endl;
	cout << "-h \t Muestra esta ayuda." << endl;
}
